custom transcriber
# support
j
i want to use custom transcriber in vapi can you please share a complete front end and backend code for it i am not able to do that just a sample code with deepgram backend
just a basic complete app plz
v
Here’s a sample backend (Node.js) code for a Vapi custom transcriber using Deepgram. This sets up a WebSocket endpoint that Vapi can connect to and streams audio to Deepgram for transcription:
Copy code
js
// server.js
const express = require("express");
const http = require("http");
const { createClient, LiveTranscriptionEvents } = require("@deepgram/sdk");
const WebSocket = require("ws");
require("dotenv").config();

const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server, path: "/api/custom-transcriber" });

const deepgram = createClient(process.env.DEEPGRAM_API_KEY);

wss.on("connection", (ws) => {
  const dgLive = deepgram.listen.live({ encoding: "linear16", sample_rate: 16000, channels: 2, model: "nova-2" });
  ws.on("message", (data, isBinary) => {
    if (isBinary) dgLive.send(data);
  });
  dgLive.on(LiveTranscriptionEvents.Transcript, (event) => {
    ws.send(JSON.stringify({ type: "transcriber-response", transcription: event.channel.alternatives[0].transcript, channel: event.channel_index[0] === 0 ? "customer" : "assistant" }));
  });
});

server.listen(3001, () => console.log("Server running on http://localhost:3001"));
Replace
process.env.DEEPGRAM_API_KEY
with your Deepgram API key in a
.env
file. This backend is ready to connect with Vapi as described in the [official documentation](https://docs.vapi.ai/customization/custom-transcriber).
Source: - [Custom transcriber documentation](https://docs.vapi.ai/customization/custom-transcriber)
j
front end
h
// server.js require('dotenv').config(); const express = require('express'); const WebSocket = require('ws'); const { createClient } = require('@deepgram/sdk'); const deepgram = createClient(process.env.DEEPGRAM_API_KEY); const app = express(); const port = process.env.PORT || 3001; const wss = new WebSocket.Server({ noServer: true }); wss.on('connection', ws => { let dgConn = null; ws.on('message', async msg => { const obj = JSON.parse(msg); if (obj.type === 'start') { dgConn = deepgram.transcription.live({ model: 'nova‑3', language: 'en‑US', smart_format: true }); dgConn.addEventListener('open', () => console.log('DG socket open')); dgConn.addEventListener('message', ev => { const data = JSON.parse(ev.data); if (data.type === 'Transcript') { const text = data.channel.alternatives[0].transcript; ws.send(JSON.stringify({ type: 'transcriber-response', transcription: text, channel: data.channel_index.includes(0) ? 'customer' : 'assistant' })); } }); dgConn.addEventListener('error', e => console.error('DG error', e)); } else if (obj.type === 'stop') { dgConn && dgConn.close(); } else if (Buffer.isBuffer(msg) || obj.type==='audio') { dgConn && dgConn.send(msg); } }); }); app.on('upgrade', (req, socket, head) => { if (req.url === '/api/custom-transcriber') { wss.handleUpgrade(req, socket, head, ws => wss.emit('connection', ws)); } else { socket.destroy(); } }); app.listen(port, () => { console.log(
Custom-transcriber server on port ${port}
); }); backend
Vapi + Deepgram Demo Start Session Stop const out = document.getElementById('output'); let ws; document.getElementById('start').onclick = () => { ws = new WebSocket('ws://localhost:3001/api/custom-transcriber'); ws.binaryType = 'arraybuffer'; ws.onopen = () => { ws.send(JSON.stringify({ type: 'start', encoding: 'linear16', container: 'raw', sampleRate: 16000, channels: 1 })); navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => { const rec = new MediaRecorder(stream, { mimeType: 'audio/webm; codecs=opus' }); rec.ondataavailable = e => { if (ws.readyState === WebSocket.OPEN) ws.send(e.data); }; rec.start(250); document.getElementById('stop').onclick = () => { rec.stop(); ws.send(JSON.stringify({ type: 'stop' })); }; }); }; ws.onmessage = msg => { const obj = JSON.parse(msg.data); if (obj.type === 'transcriber-response') { out.textContent += `${obj.channel}: ${obj.transcription}\n`; } }; };
frontend
11 Views